package com.whjh.image.conpression.task;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.factory.annotation.Value;

public class ImageCompressionTaskForkJoin {

	@Value("${image.conpression.path}")
	private String basePath;

	@Value("${image.conpression.checkDayNum}")
	private Integer checkDayNum;

	@Value("${image.conpression.limitSize:1498}")
	private Integer limitSize;

	private static ForkJoinPool forkJoinPool;

	@PostConstruct
	public void init() {
	    // 确保线程池在应用程序启动时初始化
	    if (forkJoinPool == null) {
	        forkJoinPool = new ForkJoinPool();
	    }
	}

	@PreDestroy
	public void destroy() {
	    // 确保线程池在应用程序关闭前关闭
	    if (forkJoinPool != null) {
	        forkJoinPool.shutdown();
	    }
	}
	
	private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

	protected void doExecute() throws IOException, InterruptedException {
	    int count = -checkDayNum;
	    List<String> listFileNames = new ArrayList<>();

	    while (count <= 0) {
	        count++;
	        LocalDate date = LocalDate.now().plusDays(count);
	        listFileNames.addAll(checkAndExecuteCompression(date));
	    }

	    // 创建CountDownLatch，初始值等于总任务数
	    CountDownLatch latch = new CountDownLatch(listFileNames.size());

	    // 重新遍历并提交任务，这次更新每个任务中的CountDownLatch引用
	    listFileNames.forEach(fileName -> forkJoinPool.execute(new CompressionTask(fileName, latch)));

	    // 等待所有任务完成
	    latch.await();
	}

	private List<String> checkAndExecuteCompression(LocalDate date) throws IOException {
		String dir = basePath + date.format(formatter) + "\\";
		if (!Files.exists(Paths.get(dir))) {
			return new ArrayList<>();
		}
		List<String> listFileNames = Files.walk(Paths.get(dir))
				.filter(path -> !Files.isDirectory(path))
				.map(Path::getFileName)
				.map(Path::toString)
				.collect(Collectors.toList());

		return listFileNames.stream()
                .map(fileName -> dir + fileName).collect(Collectors.toList());
	}

	private class CompressionTask implements Runnable {
		private final String filePath;
		 private final CountDownLatch latch;
		

		public CompressionTask(String filePath, CountDownLatch latch) {
			this.filePath = filePath;
			this.latch = latch;
		}

		@Override
		public void run() {
			try {
				File file = new File(filePath);
				byte[] inByte = Files.readAllBytes(file.toPath());
				long size = inByte.length;
				if (size <= limitSize) {
					return;
				}
				byte[] outByte = ThumbnailsUtils.compressPicForScaleToBytesBinarySearch(inByte, limitSize, filePath);
				Files.write(file.toPath(), outByte);
				latch.countDown();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}